#include "xmppcore/streamfeatures.h"

namespace yoohoo_xmppcore {

StreamFeature::StreamFeature(QString name, QString namespaceUri) : _name(name), _namespaceUri(namespaceUri) {
}

const QString& StreamFeature::name() const {
	return _name;
}

const QString& StreamFeature::namespaceUri() const {
	return _namespaceUri;
}

StreamFeatures::~StreamFeatures() {
	for (int i = 0; i < features.size(); i++) {
		StreamFeature* feature = features.at(i);
		supportedFeatures.removeOne(feature);
		delete feature;
	}

	for (int i = 0; i < supportedFeatures.size(); i++) {
		StreamFeature* feature = supportedFeatures.at(i);
		delete feature;
	}

	features.clear();
	supportedFeatures.clear();
}

void StreamFeatures::registerSupportedStreamFeature(StreamFeature* supported) {
	supportedFeatures.push_back(supported);
}

StreamFeature* StreamFeatures::getStreamFeature(const QString& name, const QString& namespaceUri) {
	for (int i = 0; i < features.size(); i++) {
		StreamFeature* feature = features.at(i);

		if (feature->name() == name && feature->namespaceUri() == namespaceUri)
			return feature;
	}

	return 0;
}

bool StreamFeatures::matches(QString& xml) {
	return xml.startsWith("<stream:features>");
}

const QList<StreamFeature*>& StreamFeatures::streamFeatures() const {
	return features;
}

bool StreamFeatures::fromXml(QString& xml) {
	QXmlStreamReader reader(xml);
	QXmlStreamNamespaceDeclaration namespaceDeclaration("stream", "http://etherx.jabber.org/streams");
	reader.addExtraNamespaceDeclaration(namespaceDeclaration);

	reader.readNext(); // start document
	reader.readNext(); // start element

	if (reader.hasError() || !reader.isStartElement())
		return false;

	if (reader.name().toString() != "features" && reader.prefix().toString() != "stream" &&
			reader.attributes().size() != 0)
		return false;

	reader.readNext();

	while (true) {
		if (reader.hasError())
			return false;

		if (reader.isEndElement())
			return true;

		if (reader.isEndDocument())
			return true;

		if (reader.isStartElement()) {
			ReadStreamFeatureState state = readStreamFeature(reader);
			if (state == Error)
				return false;
		}

		reader.readNext();
	}

	return false;
}

StreamFeatures::ReadStreamFeatureState StreamFeatures::readStreamFeature(QXmlStreamReader& reader) {
        qDebug("%s", qPrintable(QString("try to parse stream feature: %1,%2").arg(reader.name().toString()).arg(
			reader.namespaceUri().toString())));

	for (int i = 0; i < supportedFeatures.size(); i++) {
		StreamFeature* feature = supportedFeatures.at(i);
		if (feature->name() == reader.name().toString() &&
				feature->namespaceUri() == reader.namespaceUri().toString()) {
			if (feature->fromXml(reader)) {
				features.push_back(feature);
				return ReadOne;
			} else {
				return Error;
			}
		}
	}

	return DoNothing;
}

}
